﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;

namespace CryptoModule
{
    public static class Utils
    {
        public static void Transform(Stream input, BinaryWriter writer)
        {
            byte[] buf = new byte[4096];
            int count = -1;
            while ((count = input.Read(buf, 0, 4096)) > 0)
            {
                writer.Write(buf, 0, count);
            }
        }

        public static SymmetricAlgorithm CreateSymmetricAlgorithmInstance(EncryptionAlgorithm algorithm)
        {
            SymmetricAlgorithm instance = null;

            switch (algorithm)
            {
                case EncryptionAlgorithm.TripleDES:
                    instance = TripleDES.Create();
                    break;
                case EncryptionAlgorithm.Rijndael:
                    instance = RijndaelManaged.Create();
                    break;
                default:
                    instance = new AesCryptoServiceProvider();
                    break;
            }

            instance.Padding = PaddingMode.PKCS7;

            return instance;
        }

        public static Tuple<byte[],byte[]> ProcessKeyAndIV(SecureString userInputKey, int keySizeInByte)
        {
            IntPtr ptr=Marshal.SecureStringToBSTR(userInputKey);
            string keystr = Marshal.PtrToStringUni(ptr);
            SHA256 sha2 = SHA256.Create();
            byte[] salt = sha2.ComputeHash(System.Text.UnicodeEncoding.Unicode.GetBytes(keystr));
            Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(keystr, salt, 1200);
            byte[] key = rfc2898.GetBytes(keySizeInByte);
            return new Tuple<byte[], byte[]>(key, salt);
        }

        public static byte[] ExtractIVForFile(string file, int IVLength)
        {
            using (FileStream fs = new FileStream(file, FileMode.Open))
            {
                byte[] buf = new byte[IVLength];
                fs.Read(buf, 0, buf.Length);
                return buf;
            }
        }

        public static byte[] ExtractIVFromContent(string base64Content, int IVLength)
        {
            byte[] buf = new byte[IVLength];
            byte[] data = Convert.FromBase64String(base64Content);
            Array.Copy(data, buf, IVLength);
            return buf;
        }
    }
}
